﻿using Basic.FormCollect;
using Basic.FormModel.DB;
using Basic.FormModel.Form;
using Basic.FormModel.FormViewCol;
using Basic.FormRemoteModel;
using Basic.FormRemoteModel.Form.Model;
using Basic.FormRemoteModel.FormViewCol.Model;
using Basic.FormService.Helper;
using Basic.FormService.Interface;
using WeDonekRpc.Client;
using WeDonekRpc.Helper;

namespace Basic.FormService.lmpl
{
    internal class FormViewColService : IFormViewColService
    {
        private readonly IFormViewColCollect _Service;
        private readonly IQueryColumnCollect _Column;
        private readonly IFormViewCollect _FormView;

        public FormViewColService ( IFormViewColCollect service,
            IQueryColumnCollect column,
            IFormViewCollect formView )
        {
            this._Service = service;
            this._Column = column;
            this._FormView = formView;
        }
        public StructureColumn[] GetColumns ( FormBaseDto form, FormGetParam param )
        {
            FormViewColDto[] cols = this._Service.GetsByFormId<FormViewColDto>(form.Id, param);
            if ( cols.IsNull() )
            {
                return Array.Empty<StructureColumn>();
            }
            return cols.ConvertAll(( t, i ) =>
            {
                return new StructureColumn
                {
                    Id = t.Id,
                    Label = t.Label,
                    Name = t.Alias,
                    Type = StructureType.Column,
                    DataType = t.DataType.ToRecordDataType(),
                    FuncType = t.ColFuncType.ToDataFuncType(),
                    Sort = i
                };
            });
        }
        public FormColumn[] GetCols ( long formId, FormGetParam param )
        {
            ViewColName[] selects = this._Service.GetsByFormId<ViewColName>(formId, param);
            if ( selects.IsNull() )
            {
                return null;
            }
            return selects.ConvertAll(c => new FormColumn
            {
                Id = c.Id,
                Name = c.Alias,
                Label = c.Label
            });
        }
        public ViewBody GetBody ( long formId )
        {
            bool? isGenerate = this._FormView.Find<bool?>(formId, a => a.IsGenerate);
            if ( isGenerate.HasValue == false )
            {
                return null;
            }
            ViewColName[] selects = this._Service.GetsByFormId<ViewColName>(formId);
            return new ViewBody
            {
                IsGenerate = isGenerate.Value,
                Cols = selects.ConvertAll(c => new FormViewCol
                {
                    Id = c.Id,
                    Label = c.Label,
                    Name = c.Alias
                })
            };
        }
        public bool Set ( long id, ViewColSet set )
        {
            DBFormViewCol sour = this._Service.Get(id);
            FormViewColSet data = set.ConvertMap<ViewColSet, FormViewColSet>();
            if ( data.FuncType == PageFuncType.None )
            {
                DBPhysicalQueryColumn col = this._Column.Get(sour.ColumnId);
                data.ColFuncType = col.FuncType;
                data.DictId = col.DictId;
                data.Precision = col.Precision;
                data.ColumnSet = this._Format(col);
            }
            return this._Service.Set(sour, data);
        }
        public void Delete ( long id )
        {
            DBFormViewCol sour = this._Service.Get(id);
            this._Service.Delete(sour);
        }
        public long Add ( ViewColAdd add )
        {
            DBPhysicalQueryColumn col = this._Column.Get(add.ColumnId);
            FormViewColAdd data = add.ConvertMap<ViewColAdd, FormViewColAdd>();
            data.TableId = col.TableId;
            data.Name = col.ColName;
            if ( add.FuncType == PageFuncType.None )
            {
                data.DataType = col.DataType;
                data.ColFuncType = col.FuncType;
                data.DictId = col.DictId;
                data.Precision = col.Precision;
                data.ColumnSet = this._Format(col);
            }
            else if ( add.FuncType == PageFuncType.取周几 || add.FuncType == PageFuncType.取季度 || add.FuncType == PageFuncType.取年的第几天 )
            {
                data.DataType = PhyTableDataType.Short;
            }
            else if ( add.FuncType == PageFuncType.取年份 || add.FuncType == PageFuncType.取月份 )
            {
                data.DataType = PhyTableDataType.Short;
            }
            else if ( add.FuncType == PageFuncType.取年月 )
            {
                data.DataType = PhyTableDataType.Varchar;
            }
            else
            {
                data.DataType = col.DataType;
            }
            return this._Service.Add(data);
        }
        private Dictionary<string, object> _Format ( DBPhysicalQueryColumn col )
        {
            if ( col.ColumnSet == null )
            {
                return null;
            }
            string[] keys = new string[] { "ActiveText", "InactiveText", "Items", "DirKey", "format" };
            return col.ColumnSet.Where(c => keys.Contains(c.Key)).ToDictionary(a => a.Key, a => a.Value);
        }

        public ViewCol[] Gets ( long formId )
        {
            return this._Service.GetsByFormId<ViewCol>(formId);
        }

        public ViewCol[] Sync ( ViewColSync datum )
        {
            if ( datum.IsAppend && datum.Cols.IsNull() )
            {
                return null;
            }
            else if ( datum.Cols.IsNull() && datum.IsAppend == false )
            {
                return this._Service.Sync<ViewCol>(datum.FormId, null);
            }
            DBPhysicalQueryColumn[] cols = this._Column.Gets<DBPhysicalQueryColumn>(datum.Cols.ConvertAll(c => c.ColumnId));
            FormViewColAdd[] data = datum.Cols.ConvertAll(c =>
            {
                DBPhysicalQueryColumn col = cols.Find(a => a.Id == c.ColumnId);
                FormViewColAdd t = new FormViewColAdd
                {
                    ColumnId = c.ColumnId,
                    TableId = col.TableId,
                    FormId = datum.FormId,
                    DataType = col.DataType,
                    Name = col.ColName,
                    FuncType = c.FuncType,
                    Alias = c.Alias,
                    Label = c.Label
                };
                if ( c.FuncType == PageFuncType.None )
                {
                    t.ColFuncType = col.FuncType;
                    t.DictId = col.DictId;
                    t.Precision = col.Precision;
                    t.ColumnSet = this._Format(col);
                }
                return t;
            });
            if ( datum.IsAppend )
            {
                return this._Service.Adds<ViewCol>(data);
            }
            return this._Service.Sync<ViewCol>(datum.FormId, data);
        }
    }
}
